local GameLunch = class("GameLunch")
local GameUtils = require("utils.GameUtils")
local StoryActuator = require("gameLogic.story.StoryActuator")
local Vector3 = require("utils.Vector3")
local GameLunchActors = require("gameLogic.gameLunch.GameLunchActors")

local LEFT_BOTTOM_POS = Vector3.new(-300, 0, -300)
local RIGHT_TOP_POS = Vector3.new(300, 0, 300)

function GameLunch:ctor()
end

function GameLunch:awake()
    self._sceneId = G_SceneManager:getCurSceneId()
    self._lunchActors = GameLunchActors.new(self._sceneId, self._sceneObject)
end

function GameLunch:start()
    G_SignalManager:dispatch(SignalConst.EVENT_GAME_ENTER_SCENE, self._sceneId)
    self._joyStick = require("view.joyStick.JoyStick").new()
    self._lunchUI = require("gameLogic.ui.LunchUI").new(self._sceneId)
    if G_SocketManager:isContenting() then
        self._chatMini = require("view.chat.ChatMiniView").new()
    end
    self._signalId = G_SignalManager:beginCache()
    G_SignalManager:add(SignalConst.EVENT_NPC_TRIGGER_ADD, handler(self, self._onEventTriggerNpcAdd))
    G_SignalManager:add(SignalConst.EVENT_NPC_TRIGGER_REMOVE, handler(self, self._onEventTriggerNpcRemove))
    G_SignalManager:add(SignalConst.EVENT_ENTER_FIGHT, handler(self, self._onEventEnterFight))
    G_SignalManager:add(SignalConst.EVENT_EXIT_FIGHT, handler(self, self._onEventExitFight))
    G_SignalManager:add(SignalConst.EVENT_PLAYER_UPDATE_POS, handler(self, self._onEventPlayerUpdatePos))
    G_SignalManager:add(SignalConst.EVENT_PLAYER_UPDATE_VEC, handler(self, self._onEventPlayerUpdateVec))
    G_SignalManager:add(SignalConst.EVENT_OTHER_PLAYER_UPDATE_POS, handler(self, self._onEventOtherPlayerPos))
    G_SignalManager:add(SignalConst.EVENT_OTHER_PLAYER_UPDATE_VEC, handler(self, self._onEventOtherPlayerVel))
    G_SignalManager:add(SignalConst.EVENT_PLAYER_ENTER_SCENE, handler(self, self._onEventEnterScene))
    G_SignalManager:add(SignalConst.EVENT_PLAYER_LEAVE_VIEW, handler(self, self._onEventPlayerLeave))
    G_SignalManager:add(SignalConst.EVENT_USER_FLUSH_DATA, handler(self, self._onEventFlush))
    G_SignalManager:add(SignalConst.EVENT_TEAM_GROUP_NOTIFY, handler(self, self._onEventTeamNotify))
    G_SignalManager:add(SignalConst.EVENT_DEL_TEAM_GROUP, handler(self, self._onEventDelTeam))
    G_SignalManager:add(SignalConst.EVENT_QUIT_TEAM_GROUP, handler(self, self._onEventQuitTeam))
    G_SignalManager:add(SignalConst.EVENT_INVITE_TEAM_GROUP, handler(self, self._onEventInviteTeam))
    G_SignalManager:add(SignalConst.EVENT_TEAM_GROUP_ENTER_SCENE, handler(self, self._onEventTeamEnterScene))
    G_SignalManager:add(SignalConst.EVENT_SCENE_NOTIFY_MONSTER, handler(self, self._onEventNotifyMonster))
    G_SignalManager:add(SignalConst.EVENT_SCENE_MONSTER_LEAVE_VIEW, handler(self, self._onEventMonsterLeaveView))
    G_SignalManager:add(SignalConst.EVENT_MONSTER_TRACK_PLAYER, handler(self, self._onEventMonsterTrackPlayer))
    G_SignalManager:add(SignalConst.EVENT_MONSTER_FIGHT_PLAYER, handler(self, self._onEventMonsterFightPlayer))
    G_SignalManager:add(SignalConst.EVENT_MONSTER_STATUS_NOTIFY, handler(self, self._onEventMonsterStatusNotify))
    G_SignalManager:endCache()
    self:_enterScene()
end

function GameLunch:update(dt)
    self._lunchActors:moveOtherPlayers(dt)
    self._player:updateDt(dt, self._joyStick.horizontal, self._joyStick.vertical)
end

function GameLunch:_enterScene()
    local pos = self._player.transform.position
    local forward = self._player.transform.forward
    G_UserData:getBase():c2sEnterScane(self._sceneId, pos, forward)
end

function GameLunch:onDestroy()
    self._lunchUI:close()
    self._joyStick:close()
    if self._chatMini then
        self._chatMini:close()
    end
    if self._teamGroup then
        self._teamGroup:close()
    end
    G_SignalManager:removeCache(self._signalId)
end

function GameLunch:_onNpcUIClose()
    self._npcTalkUI = nil
end

function GameLunch:_onEventTriggerNpcAdd(id, triggerId, type)
    if not self._npcTalkUI then
        self._npcTalkUI = require("view.Npc.NpcTalkUI").new(handler(self, self._onNpcUIClose))
    end
    self._npcTalkUI:addNpcTalk(triggerId)
end

function GameLunch:_onEventTriggerNpcRemove(id, npcId, type)
    if self._npcTalkUI then
        self._npcTalkUI:removeTalkUI(npcId)
    end
end

function GameLunch:_onEventEnterFight(id, pos)
    self:_enterFight(pos)
end

function GameLunch:_onEventExitFight(id, message)
    self:_exitFight()
end

function GameLunch:_enterFight(pos)
    self._player:resetMoveDirection()
    self._lunchUI.gameObject:SetActive(false)
    self._joyStick:hide(true)
    self._sceneObject:SetActive(false)

    local popup = require("view.popup.FightTransition").new()
    popup:setTip(Lang.get("lang_enter_fight_tip"))
    popup:play(
        function()
        end
    )
    local object = G_ResourceManager:loadPrefabs("Prefabs/Other/FightRoot")
    local fightRoot = GameUtils.instantiate(object)
    fightRoot.transform.position = pos
end

function GameLunch:_exitFight()
    self._lunchUI.gameObject:SetActive(true)
    self._joyStick:hide(false)
    self._sceneObject:SetActive(true)
end

function GameLunch:_onEventPlayerUpdatePos(id, forward, position)
    G_UserData:getBase():c2sUpdatePos(self._sceneId, position, forward)
end

function GameLunch:_onEventPlayerUpdateVec(id, forward, position, vec)
    G_UserData:getBase():c2sUpdateVelocity(self._sceneId, position, forward, vec)
end

function GameLunch:_onEventOtherPlayerPos(id, sceneId, userId, pos, forward)
    if self._sceneId == sceneId then
        local param = {}
        param.userId = userId
        param.pos = Vector3.new(pos.x, pos.y, pos.z)
        param.forward = Vector3.new(forward.x, forward.y, forward.z)
        self._lunchActors:updateOtherPlayer(param)
    end
end

function GameLunch:_onEventOtherPlayerVel(id, sceneId, userId, pos, forward, velocity)
    if sceneId == self._sceneId then
        local param = {}
        param.userId = userId
        param.pos = Vector3.new(pos.x, pos.y, pos.z)
        param.forward = Vector3.new(forward.x, forward.y, forward.z)
        param.velocity = Vector3.new(velocity.x, velocity.y, velocity.z)
        self._lunchActors:updateOtherPlayer(param)
    end
end

function GameLunch:_onEventEnterScene(id, sceneId, userId, pos, forward)
end

function GameLunch:_onEventPlayerLeave(id, userId)
    self._lunchActors:removePlayer(userId)
end

function GameLunch:_onEventFlush()
    local pos = self._player.transform.position
    local forward = self._player.transform.forward
    self._lunchActors:clearOtherPlayer()
    self._lunchActors:clearMonsters()
    G_UserData:getBase():c2sEnterScane(self._sceneId, pos, forward)
end

function GameLunch:_onEventTeamNotify(id, message)
    if self._teamGroup then
        return
    end
    self._teamGroup =
        require("view.teamGroup.TeamGroupView").new(
        self._sceneId,
        function()
            self._teamGroup = nil
        end
    )
end

function GameLunch:_onEventDelTeam(id, targetId)
    if targetId == 0 then
        return
    end
    local cfg = require("config.monsterhole").get(targetId)
    if cfg.scene == self._sceneId then
        self._lunchActors:clearOtherPlayer()
    end
end

function GameLunch:_onEventQuitTeam(id, targetId)
    if targetId == 0 then
        return
    end
    local cfg = require("config.monsterhole").get(targetId)
    if cfg.scene == self._sceneId then
        self._lunchActors:clearOtherPlayer()
    end
end

function GameLunch:_onEventInviteTeam(id, user, teamId, targetId)
    if self._popInvite then
        return
    end
    self._popInvite =
        require("view.teamGroup.PopupInviteTeamGroup").new(
        teamId,
        user,
        targetId,
        function()
            self._popInvite = nil
        end
    )
end

function GameLunch:_onEventTeamEnterScene(id, sceneId)
    if self._sceneId ~= sceneId then
        G_SceneManager:loadSceneAnsc(sceneId)
    end
end

function GameLunch:_onEventNotifyMonster(id, sceneId, monsterId, pos, isFight)
    if self._sceneId == sceneId then
        local monsPos = Vector3.new(pos.x, pos.y, pos.z)
        self._lunchActors:addMonster(monsterId, pos, isFight)
    end
end

function GameLunch:_onEventMonsterLeaveView(id, sceneId, monsterId)
    if self._sceneId == sceneId then
        self._lunchActors:removeMonster(monsterId)
    end
end

function GameLunch:_onEventMonsterTrackPlayer(id, sceneId, monsterId, trackId)
    if self._sceneId == sceneId then
        self._lunchActors:monsterTrack(monsterId, trackId)
    end
end

function GameLunch:_onEventMonsterFightPlayer(id, sceneId, monsterId, fightId)
    if self._sceneId == sceneId then
        self._lunchActors:setMonsterFight(monsterId, true)
    end
end

function GameLunch:_onEventMonsterStatusNotify(id, sceneId, monsterId, status, topos)
    if self._sceneId == sceneId then
        self._lunchActors:setMonsterStatus(monsterId, status, topos)
    end
end

return GameLunch
